using System;
using System.Activities;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

namespace CRM2011WorkflowUtilities
{
    public class Delete : CodeActivity
    {
        protected override void Execute(CodeActivityContext executionContext)
        {
            try  
            {
                //Create the context and tracing service
                IExecutionContext context = executionContext.GetExtension<IExecutionContext>();
                IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
                ITracingService tracer = executionContext.GetExtension<ITracingService>();

                if (PrimaryEntity.Get(executionContext))
                {
                    tracer.Trace("Deleting process primary entity");
                    service.Delete(context.PrimaryEntityName, context.PrimaryEntityId);
                }
                else
                {
                    string relatedAttribute = RelatedAttributeName.Get(executionContext);
                    if (string.IsNullOrEmpty(relatedAttribute))
                    {
                        Helpers.Throw("If deleting related entity, related attribute name must be specified in the process delete step configuration");
                    }

                    // Retrieve primary entity with the required attribute
                    tracer.Trace("Retrieving process primary entity");
                    Entity primaryEntity = service.Retrieve(context.PrimaryEntityName, context.PrimaryEntityId, new ColumnSet(relatedAttribute));

                    if (primaryEntity.Contains(relatedAttribute))
                    {
                        EntityReference reference = primaryEntity[relatedAttribute] as EntityReference;
                        if (reference == null)
                        {
                            Helpers.Throw(string.Format("The attribute {0} on entity {1} is expected to be of EntityReference type",
                                relatedAttribute, context.PrimaryEntityName));
                        }

                        tracer.Trace("Deleting entity related to primary entity by attribute " + relatedAttribute);
                        service.Delete(reference.LogicalName, reference.Id);
                    }

                }
                

            }
            catch (Exception ex)
            {
               Helpers.Throw(String.Format("An error occurred in the {0} plug-in.",
                       this.GetType().ToString()),
                     ex);
            }

            return;
        }

        #region Input Parameters

        [RequiredArgument]
        [Input("Delete primary entity (True) or related entity (False)")]
        public InArgument<bool> PrimaryEntity { get; set; }

        [Input("If deleting related entity, specify attribute name to get the related entity")]
        public InArgument<string> RelatedAttributeName { get; set; }

        #endregion

        #region Output Parameters
        #endregion
    }
}
